/*
 * Copyright 2004-2006 公司名
 * 本软件及其所有拷贝的名称，与光盘上或本软件中注明的公司同在。
 * 本软件及文档享有版权，并受国家版权法及国际协约条款的保护。
 * 您不可以从本软件中去掉其版权声明；并保证为本软件的拷贝（本部或部分）复制版权声明。
 * 您同意制止以任何形式非法拷贝本软件及文档。
 * 版权信息参见：
 *      http://www.companyname.cn/licenses
 */

package com.companyname.common.sysframe.model;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import com.companyname.common.base.model.BaseObject;
import com.companyname.common.base.util.BaseObjectPriAscComparator;
import com.companyname.common.sysframe.define.UserStatus;
import com.companyname.common.sysframe.util.CompanyNameSysFrameException;
import com.companyname.common.util.endecode.UniqueKey;
import com.companyname.common.viewframe.model.Area;
import com.companyname.common.viewframe.model.Column;
import com.companyname.common.viewframe.model.Home;

/**
 * <p>Title: 人员 </p>
 * <p>Description: 人员 User </p>
 * <p>Copyright: Copyright (c) 2004-2006</p>
 * <p>Company: 公司名</p>
 * @ $Author: 作者名 $
 * @ $Date: 创建日期 $
 * @ $Revision: 1.0 $
 * @ created in 创建日期
 *
 */

public class User extends BaseObject
                  implements Serializable
{
        static Logger logger = Logger.getLogger(User.class);
        
        // account(帐号：代码上实现唯一约束；由于人员采用作废机制，无法做帐号唯一性约束)
        private String account;

        // family_name(姓)
        private String familyName;

        // given_name(名)
        private String givenName;

        // password(密码)
        private String password;

        // birthday(生日)
        private Timestamp birthday;

        // address(地址)
        private String address;

        // email(电邮)
        private String email;

        // phone(电话)
        private String phone;

        // home_site(个人主页)
        private String homeSite;

        // mobile(手机号)
        private String mobile;

        // status
        private int status;

        // pw_limt_date(密码有效期)
        private Timestamp pwLimtDate;

        // id_limt_date(帐号有效期)
        private Timestamp idLimtDate;

        // pw_error_num(密码错误次数)
        private int pwErrorNum;

        // pw_error_lock(密码错误锁定帐号次数)
        private int pwErrorLock;

        // remark(备注)
        private String remark;
        
        private Set post2Users;

        /**
         * 构造函数
         */
        public User()
        {
                // for hibernate
        }
        
        public User(String account,
                    String familyName,
                    String givenName,
                    String pri)
        {
                this.account = account;
                this.familyName = familyName;
                this.givenName = givenName;
                this.pri = pri;
                this.resetPW("123456");
                this.birthday = new Timestamp(System.currentTimeMillis());
                this.address = "";
                this.email = "";
                this.phone = "";
                this.homeSite = "";
                this.mobile = "";
                this.status = UserStatus.VALID;
                this.remark = "";
                Timestamp after10Years = new Timestamp(System.currentTimeMillis());
                after10Years.setYear(after10Years.getYear() + 10);
                this.idLimtDate = after10Years;
                this.pwLimtDate = after10Years;
                
        }
        
        /**
         * @return 返回 account。
         */
        public String getAccount()
        {
                return account;
        }

        /**
         * @param account 要设置的 account。
         */
        public void setAccount(String account)
        {
                this.account = account;
        }

        /**
         * @return 返回 address。
         */
        public String getAddress()
        {
                return address;
        }

        /**
         * @param address 要设置的 address。
         */
        public void setAddress(String address)
        {
                this.address = address;
        }

        /**
         * @return 返回 birthday。
         */
        public Timestamp getBirthday()
        {
                return birthday;
        }
        
        public String getFormatedBirthday()
        {
                if(this.birthday != null)
                        return this.formatDate(this.birthday,"yyyy-MM-dd");
                else
                        return "";
        }

        /**
         * @param birthday 要设置的 birthday。
         */
        public void setBirthday(Timestamp birthday)
        {
                this.birthday = birthday;
        }

        /**
         * @return 返回 email。
         */
        public String getEmail()
        {
                return email;
        }

        /**
         * @param email 要设置的 email。
         */
        public void setEmail(String email)
        {
                this.email = email;
        }

        /**
         * @return 返回 familyName。
         */
        public String getFamilyName()
        {
                return familyName;
        }

        /**
         * @param familyName 要设置的 familyName。
         */
        public void setFamilyName(String familyName)
        {
                this.familyName = familyName;
        }

        /**
         * @return 返回 givenName。
         */
        public String getGivenName()
        {
                return givenName;
        }

        /**
         * @param givenName 要设置的 givenName。
         */
        public void setGivenName(String givenName)
        {
                this.givenName = givenName;
        }
        
        public String getName()
        {
                return this.familyName + this.givenName;
        }
        
        /**
         * @return 返回 homeSite。
         */
        public String getHomeSite()
        {
                return homeSite;
        }

        /**
         * @param homeSite 要设置的 homeSite。
         */
        public void setHomeSite(String homeSite)
        {
                this.homeSite = homeSite;
        }

        /**
         * @return 返回 idLimtDate。
         */
        public Timestamp getIdLimtDate()
        {
                return idLimtDate;
        }
        
        public String getFormatedIdLimtDate()
        {
                return this.formatDate(this.idLimtDate,"yyyy-MM-dd");
        }
        
        /**
         * @param idLimtDate 要设置的 idLimtDate。
         */
        public void setIdLimtDate(Timestamp idLimtDate)
        {
                this.idLimtDate = idLimtDate;
        }

        /**
         * @return 返回 mobile。
         */
        public String getMobile()
        {
                return mobile;
        }

        /**
         * @param mobile 要设置的 mobile。
         */
        public void setMobile(String mobile)
        {
                this.mobile = mobile;
        }

        /**
         * @return 返回 password。
         */
        public String getPassword()
        {
                return password;
        }

        /**
         * @param password 要设置的 password。
         */
        public void setPassword(String password)
        {
                this.password = password;
        }
        
        // 检测密码是否正确
        public boolean checkPW(String pw)
        {
                try
                {
                        return (this.password.equals(UniqueKey.encodePassword(this.account + pw)));
                }
                catch(Exception x)
                {
                        logger.error("校验密码失败：" + x.toString());
                        throw new CompanyNameSysFrameException("校验密码失败：" + x.toString());
                }
        }
        
        // 重新设置密码
        public void resetPW(String pw)
        {
                try
                {
                        this.password = UniqueKey.encodePassword(this.account + pw);
                }
                catch(Exception x)
                {
                        logger.error("设置密码失败:" + x.toString());
                        throw new CompanyNameSysFrameException("设置密码失败:" + x.toString());
                }
        }

        /**
         * @return 返回 phone。
         */
        public String getPhone()
        {
                return phone;
        }

        /**
         * @param phone 要设置的 phone。
         */
        public void setPhone(String phone)
        {
                this.phone = phone;
        }

        /**
         * @return 返回 post2Users。
         */
        public Set getPost2Users()
        {
                return post2Users;
        }

        /**
         * @param post2Users 要设置的 post2Users。
         */
        public void setPost2Users(Set post2Users)
        {
                this.post2Users = post2Users;
        }
        
        public void addPost2User(Post2User p2u)
        {
                if(this.post2Users == null)
                {
                        this.post2Users = new LinkedHashSet();
                }
                this.post2Users.add(p2u);
        }
        
        public void addPost(Post post,int index)
        {
                Post2User p2u = new Post2User();
                p2u.setPri(Long.toString(System.currentTimeMillis() + index));
                p2u.setPost(post);
                p2u.setUser(this);
                this.addPost2User(p2u);
        }
        
        public void addPosts(List posts)
        {
                for(int i = 0; i < posts.size(); i++)
                {
                        Post post = (Post)posts.get(i);
                        this.addPost(post,i);
                }
        }
        
        public void setPosts(Set posts)
        {
                this.post2Users = null;
                Object[] ps = posts.toArray();
                for(int i = 0; i < ps.length; i ++)
                {
                        Post post = (Post)ps[i];
                        this.addPost(post,i);
                }
        }
        // 取得所有岗位
        public List getPosts()
        {
                Set posts = new LinkedHashSet(this.post2Users.size());
                Object[] p2us = this.post2Users.toArray();
                for(int i = 0; i < p2us.length; i ++)
                {
                        Post2User p2u = (Post2User)p2us[i];
                        posts.add(p2u.getPost());
                }
                return new ArrayList(posts);
        }
        
        // 取得首岗位
        public Post getFirstPost()
        {
                if(this.post2Users.size() == 0)
                {
                        return null;
                }
                else
                {
                        Post fp = ((Post2User)this.post2Users.toArray()[0]).getPost();
                        return fp;
                }
        }
        
        // 取得所有机构
        public List getOrgs()
        {
                Set orgs = new LinkedHashSet(this.post2Users.size());
                Object[] p2us = this.post2Users.toArray();
                for(int i = 0; i < p2us.length; i ++)
                {
                        Post2User p2u = (Post2User)p2us[i];
                        orgs.add(p2u.getPost().getOrg());
                }
                return new ArrayList(orgs);
        }
        
        // 根据机构code取得机构
        public Org getOrgByCode(String orgCode)
        {
                Object[] p2us = this.post2Users.toArray();
                for(int i = 0; i < p2us.length; i ++)
                {
                        Post2User p2u = (Post2User)p2us[i];
                        if(p2u.getPost().getOrg().getCode().equals(orgCode))
                        {
                                return p2u.getPost().getOrg();
                        }
                }
                return null;
        }
        
        // 首机构
        public Org getFirstOrg()
        {
                if(this.post2Users.size() == 0)
                {
                        return null;
                }
                else
                {
                        Post fp = ((Post2User)this.post2Users.toArray()[0]).getPost();
                        return fp.getOrg();
                }
        }        
        
        // 取得所有角色
        public List getRoles()
        {
                Set orgs = new LinkedHashSet(this.post2Users.size());
                Object[] p2us = this.post2Users.toArray();
                for(int i = 0; i < p2us.length; i ++)
                {
                        Post2User p2u = (Post2User)p2us[i];
                        orgs.add(p2u.getPost().getRole());
                }
                return new ArrayList(orgs);
        }
        
        // 根据角色code取得角色
        public Role getRoleByCode(String roleCode)
        {
                Object[] p2us = this.post2Users.toArray();
                for(int i = 0; i < p2us.length; i ++)
                {
                        Post2User p2u = (Post2User)p2us[i];
                        if(p2u.getPost().getRole().getCode().equals(roleCode))
                        {
                                return p2u.getPost().getRole();
                        }
                }
                return null;
        }
        
        /**
         * @return 返回 pwErrorLock。
         */
        public int getPwErrorLock()
        {
                return pwErrorLock;
        }

        /**
         * @param pwErrorLock 要设置的 pwErrorLock。
         */
        public void setPwErrorLock(int pwErrorLock)
        {
                this.pwErrorLock = pwErrorLock;
        }

        /**
         * @return 返回 pwErrorNum。
         */
        public int getPwErrorNum()
        {
                return pwErrorNum;
        }

        /**
         * @param pwErrorNum 要设置的 pwErrorNum。
         */
        public void setPwErrorNum(int pwErrorNum)
        {
                this.pwErrorNum = pwErrorNum;
        }

        /**
         * @return 返回 pwLimtDate。
         */
        public Timestamp getPwLimtDate()
        {
                return pwLimtDate;
        }
        
        public String getFormatedPwLimtDate()
        {
                return this.formatDate(this.pwLimtDate,"yyyy-MM-dd");
        }

        /**
         * @param pwLimtDate 要设置的 pwLimtDate。
         */
        public void setPwLimtDate(Timestamp pwLimtDate)
        {
                this.pwLimtDate = pwLimtDate;
        }

        /**
         * @return 返回 remark。
         */
        public String getRemark()
        {
                return remark;
        }

        /**
         * @param remark 要设置的 remark。
         */
        public void setRemark(String remark)
        {
                this.remark = remark;
        }

        /**
         * @return 返回 status。
         */
        public int getStatus()
        {
                return status;
        }
        
        public String getStatusName()
        {
                return UserStatus.NAMES[this.status];
        }

        /**
         * @param status 要设置的 status。
         */
        public void setStatus(int status)
        {
                this.status = status;
        }
        
        public List getHomes()
        {
                Set tmpHomes = new LinkedHashSet();
                List posts = this.getPosts();
                for(int i = 0; i < posts.size(); i ++)
                {
                        Post post = (Post)posts.get(i);
                        tmpHomes.addAll(post.getAuthorizedHomes(false));
                        tmpHomes.addAll(post.getOrg().getAuthorizedHomes(false));
                        tmpHomes.addAll(post.getRole().getAuthorizedHomes(false));
                }// for i
                List homes = new ArrayList(tmpHomes);
                Collections.sort(homes,new BaseObjectPriAscComparator());
                return homes;
        }
        
        public Home getHome(String homeCode)
        {
                List homes = this.getHomes();
                for(int i = 0; i < homes.size(); i ++)
                {
                        Home home = (Home)homes.get(i);
                        if(home.getCode().equals(homeCode))
                        {
                                return home;
                        }
                }
                return null;
        }
        
        public List getAreas()
        {
                Set tmpAreas = new LinkedHashSet();
                List posts = this.getPosts();
                for(int i = 0; i < posts.size(); i ++)
                {
                        Post post = (Post)posts.get(i);
                        tmpAreas.addAll(post.getAuthorizedAreas(false));
                        tmpAreas.addAll(post.getOrg().getAuthorizedAreas(false));
                        tmpAreas.addAll(post.getRole().getAuthorizedAreas(false));
                }// for i
                List areas = new ArrayList(tmpAreas);
                Collections.sort(areas,new BaseObjectPriAscComparator());
                return areas;
        }
        
        public Area getArea(String areaCode)
        {
                List areas = this.getAreas();
                for(int i = 0; i < areas.size(); i ++)
                {
                        Area area = (Area)areas.get(i);
                        if(area.getCode().equals(areaCode))
                        {
                                return area;
                        }
                }
                return null;
        }
        
        public List getColumns()
        {
                Set columns = new LinkedHashSet();
                List posts = this.getPosts();
                for(int i = 0; i < posts.size(); i ++)
                {
                        Post post = (Post)posts.get(i);
                        columns.addAll(post.getAuthorizedColumns(false));
                        columns.addAll(post.getOrg().getAuthorizedColumns(false));
                        columns.addAll(post.getRole().getAuthorizedColumns(false));
                }// for i
                List cs = new ArrayList(columns); 
                Collections.sort(cs,new BaseObjectPriAscComparator());
                return cs;
        }
        
        public Column getColumn(String columnCode)
        {
                List columns = this.getColumns();
                for(int i = 0; i < columns.size(); i ++)
                {
                        Column column = (Column)columns.get(i);
                        if(column.getCode().equals(columnCode))
                        {
                                return column;
                        }
                }
                return null;
        }

        /** 采用框架提供的操作日志必须填写的项目 */
        public void setModeldetail()
        {
                this.setModelFieldDetail("id",this.getId());
                this.setModelFieldDetail("帐号",this.account);
                this.setModelFieldDetail("姓名",this.getName());
                if(this.post2Users != null 
                && this.post2Users.size() != 0)
                {
                        Object[] p2us = this.post2Users.toArray();
                        for(int i = 0; i < p2us.length; i ++)
                        {
                                Post2User p2u = (Post2User)p2us[i];
                                this.setModelFieldDetail("岗位",p2u.getPost().getName());
                        }
                }
                this.setModelFieldDetail("生日",this.getFormatedBirthday());
                this.setModelFieldDetail("地址",this.address);
                this.setModelFieldDetail("电邮",this.email);
                this.setModelFieldDetail("电话",this.phone);
                this.setModelFieldDetail("个人主页",this.homeSite);
                this.setModelFieldDetail("手机号",this.mobile);
                this.setModelFieldDetail("密码有效期",this.getFormatedPwLimtDate());
                this.setModelFieldDetail("帐号有效期",this.getFormatedIdLimtDate());
                this.setModelFieldDetail("密码错误次数",this.getPwErrorNum());
                this.setModelFieldDetail("密码错误锁定帐号次数",this.getPwErrorLock());
                this.setModelFieldDetail("优先级",this.pri);
                this.setModelFieldDetail("状态",this.getStatusName());
        }
}
